const http = require('http');
const { spawn } = require('child_process');
const url = require('url');

// 创建HTTP服务器
const server = http.createServer((req, res) => {
  // 设置CORS头
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
  
  if (req.method === 'OPTIONS') {
    res.writeHead(200);
    res.end();
    return;
  }
  
  // 解析URL参数
  const parsedUrl = url.parse(req.url, true);
  const rtspUrl = parsedUrl.query.rtsp;
  const format = parsedUrl.query.format || 'mp4'; // 支持mp4, flv, mpegts
  const transport = parsedUrl.query.transport || 'tcp'; // 支持tcp, udp
  
  if (!rtspUrl) {
    res.writeHead(400, { 'Content-Type': 'text/plain' });
    res.end('缺少RTSP URL参数');
    return;
  }
  
  console.log(`开始处理RTSP流: ${rtspUrl}`);
  console.log(`格式: ${format}, 传输: ${transport}`);
  
  // 设置响应头
  const contentType = format === 'mp4' ? 'video/mp4' : 
                     format === 'flv' ? 'video/x-flv' : 
                     'video/mp2t';
  
  res.writeHead(200, {
    'Content-Type': contentType,
    'Access-Control-Allow-Origin': '*',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive'
  });
  
  try {
    // 根据格式选择不同的FFmpeg参数
    let ffmpegArgs = [
      '-rtsp_transport', transport,
      '-i', rtspUrl,
      '-c:v', 'libx264',
      '-c:a', 'aac',
      '-preset', 'ultrafast',
      '-tune', 'zerolatency',
      '-analyzeduration', '2000000',
      '-probesize', '2000000',
      '-fflags', '+genpts+igndts',
      '-avoid_negative_ts', 'make_zero',
      '-b:v', '800k',
      '-b:a', '128k',
      '-r', '25',
      '-s', '1280x720',
      '-g', '25',
      '-keyint_min', '25',
      '-sc_threshold', '0',
      '-bf', '0',
      '-refs', '1',
      '-profile:v', 'baseline',
      '-level', '3.1',
      '-pix_fmt', 'yuv420p',
      '-x264opts', 'no-scenecut'
    ];
    
    // 根据格式添加特定参数
    if (format === 'mp4') {
      ffmpegArgs = ffmpegArgs.concat([
        '-f', 'mp4',
        '-movflags', '+frag_keyframe+empty_moov+faststart',
        '-frag_duration', '1000000',
        '-max_muxing_queue_size', '1024'
      ]);
    } else if (format === 'flv') {
      ffmpegArgs = ffmpegArgs.concat([
        '-f', 'flv',
        '-flvflags', 'no_duration_filesize'
      ]);
    } else if (format === 'mpegts') {
      ffmpegArgs = ffmpegArgs.concat([
        '-f', 'mpegts',
        '-mpegts_flags', '+initial_discontinuity'
      ]);
    }
    
    ffmpegArgs.push('pipe:1');
    
    console.log('启动FFmpeg进程:', ffmpegArgs.join(' '));
    
    const ffmpegProcess = spawn('ffmpeg', ffmpegArgs, {
      stdio: ['ignore', 'pipe', 'pipe']
    });
    
    // 处理FFmpeg输出
    ffmpegProcess.stdout.on('data', (data) => {
      res.write(data);
    });
    
    // 处理FFmpeg错误输出
    ffmpegProcess.stderr.on('data', (data) => {
      const stderr = data.toString();
      console.log('FFmpeg stderr:', stderr);
    });
    
    // 处理FFmpeg进程结束
    ffmpegProcess.on('close', (code) => {
      console.log(`FFmpeg进程结束，退出码: ${code}`);
      res.end();
    });
    
    // 处理FFmpeg进程错误
    ffmpegProcess.on('error', (error) => {
      console.log('FFmpeg进程错误:', error);
      res.writeHead(500, { 'Content-Type': 'text/plain' });
      res.end(`FFmpeg进程错误: ${error.message}`);
    });
    
    // 处理客户端断开连接
    req.on('close', () => {
      console.log('客户端断开连接');
      ffmpegProcess.kill('SIGTERM');
    });
    
  } catch (error) {
    console.log('启动FFmpeg失败:', error);
    res.writeHead(500, { 'Content-Type': 'text/plain' });
    res.end(`启动FFmpeg失败: ${error.message}`);
  }
});

// 启动服务器
const PORT = 8080;
server.listen(PORT, () => {
  console.log(`通用RTSP流服务器已启动，监听端口 ${PORT}`);
  console.log('使用示例:');
  console.log('MP4格式: http://localhost:8080?rtsp=rtsp://your-rtsp-url&format=mp4');
  console.log('FLV格式: http://localhost:8080?rtsp=rtsp://your-rtsp-url&format=flv');
  console.log('MPEGTS格式: http://localhost:8080?rtsp=rtsp://your-rtsp-url&format=mpegts');
  console.log('UDP传输: http://localhost:8080?rtsp=rtsp://your-rtsp-url&transport=udp');
}); 